<template>
  <div class="m-chat">
    <!-- 左侧联系人列表 -->
    <aside class="m-chat-aside">
       <!-- 聊天联系人列表 -->
        <p class="JIMUserList-null" v-if="JIMUserList && !JIMUserList.length">暂无用户列表</p>
        <dl v-else class="list" 
          v-for="(user, index) in JIMUserList" 
          :key="index"
          :class="{actived: user.adminId == JIMTargetUser.adminId}"
          @click="onSelectUser(user)">
          <dt class="avatar">
            <img :src="user.buyImg || avatar">
          </dt>
          <dd class="ct">
            <p class="name">{{user.buyName}}</p>
            <div class="msg-bd">
              <p class="msg">{{user.message[user.message.length-1].text | filterLastMsg}}</p>
            </div>
          </dd>
        </dl>
    </aside>

    <!-- 聊天主体内容 -->
    <div class="m-chat-bd">

      <!-- 头部店铺名称和关闭 -->
      <header>
        <h1 class="name">{{JIMTargetUser.storeName}}</h1>
        <i class="close" @click="onCloseJIM"></i>
      </header>

      <!-- 聊天内容 -->
      <div class="chat-bd" id="chatBody">
        <div class="msg-bd"
          v-for="(msg, index) in JIMTargetUser.message" 
          :key="index"
          :class="{'opposite-msg-bd': !msg.ident, 'mine-msg-bd': msg.ident}">
          <!-- 头像 -->
          <div class="avatar">
            <img :src="msg.ident ? (JIMTargetUser.storeLogo || avatar) : (JIMTargetUser.buyImg || avatar)">
          </div>
          <!-- 图文结合的消息(第一次点击店铺时发送) -->
          <div v-if="msg.goods" class="ct photo-text clearfix">
            <img :src="msg.text.goods_main_photo" />
            <p>{{msg.text.goodsName}}</p> 
          </div>
          <!-- 消息内容 -->
          <div v-else class="ct">{{msg.text}}</div>
        </div>
      </div>

      <!-- 聊天工具栏 -->
      <div class="tool-bd">
        <button class="face" @click.stop="onEmojiVisible"></button>
        <w-emoji v-show="isEmoji" @on-select="onSelectEmoji"></w-emoji>
      </div>

      <!-- 聊天输入框 -->
      <div class="input-bd">
        <textarea id="chatMsg" v-model="chatMsg" @keydown.13="onSendMsg" @click="onClickText"></textarea>
        <w-button :type="isNoSend ? 'disabled' : 'main'" @click.native="onSendMsg" :disabled="isNoSend">发送</w-button>
      </div>
    </div>
  </div>
</template>

<script>
  import { mapActions, mapGetters, mapMutations } from 'vuex'
  import { apiChatSendMsg } from 'js/api'
  import { session } from 'js/util'

  export default {
    data() {
      return {
        appkey: this.$store.getters.appkey,
        chatMsg: '', // 聊天的信息
        userInfo: session.get('userInfo') || {}, // 本用户的个人信息
        avatar: require('./pic_avatar.png'),
        isEmoji: false, // 控制表情框显示隐藏
        isNoSend: false
      }
    },
    created() {
      this._initJIM()
    },
    mounted() {
      JIM.onDisconnect(data => {
        this._initJIM()
      })
    },
    methods: {
      ...mapActions(['JIMInit']),
      ...mapMutations(['setJIMUserList', 'setJIMTargetUser']),
      // 初始化
      _initJIM() {
        const _this = this
        const token = this.userInfo.accessToken
        // 判断用户是否登录
        if (token) {
          // 判断JM是否init，如果init则直接登录
          if (JIM.isInit()) {
            this._isJIMLogin()
          } else { // 没有init，则开始init
            this.JIMInit({
              onSuccess() {
                _this._isJIMLogin()
              }
            })
          }
        } else { // 用户没登录
          this.$toast('亲，请先登录', () => {
            this.$router.push('/login')
          })
        }
      },
      // 判断是否登录
      _isJIMLogin() {
        // 未登录，则调用登录，进行聊天
        if (!JIM.isLogin()) {
          this._JIMLogin(() => {
            this._listenJIMSyncMsg()
            this._listenReceviceMsg()
          })
        }
      },
      // JIM登录，以及登录后的操作
      _JIMLogin(callback) {
        JIM.login({
          username: this.userInfo.userName,
          password: this.userInfo.userName
        }).onSuccess(data => {
          callback && callback()
        })
      },
      // 获取历史记录消息监听
      _listenJIMSyncMsg() {
        // 获取手机号码，toId
        const username = this.userInfo.userName
        JIM.onSyncConversation(data => {
          data = data || []
          // 如果有离线数据
          if (data.length) {
            // 处理过后的历史消息数组
            let aNewMsg = []
            // 遍历所有的历史用户
            data.forEach(amessage => {
              amessage = amessage.msgs || []
              // 找到是我发送的消息的from_id
              const curIndex = amessage.findIndex(item => {
                return item.content.target_id == username
              })
              if (curIndex < 0) return
              // 处理发送和接受的fromId
              const oSendInfo = amessage[curIndex].content.msg_body.extras || {}
              // 处理后的对象
              let oMsg = {
                ...oSendInfo,
                adminId: amessage[curIndex].content.from_id,
                message: [] // 插入的历史消息，和现在聊天所发送的消息
              }
              // 遍历用户下的所有信息，并处理成需要的格式
              amessage.forEach(msg => {
                if (msg.content.from_id != username) {
                  let body = msg.content.msg_body.text
                  body = /"goods_main_photo"/.test(body) ? JSON.parse(body) : body
                  // 插入对方的消息信息 插入自己发送的消息，有goods的是图文结合的消息
                  oMsg.message.push({
                    text: body,
                    goods: typeof body == 'object'
                  })
                } else {
                  oMsg.message.push({
                    text: msg.content.msg_body.text,
                    ident: true
                  })
                }
              })
              // 取到的历史用户记录列表
              aNewMsg.push(oMsg)
            })
            this.setJIMUserList(aNewMsg)
            this.setJIMTargetUser(aNewMsg[0])
            this._scrollToBottom()
          }
        })
      },
      // 实时消息监听
      _listenReceviceMsg() {
        JIM.onMsgReceive(data => {
          const content = data.messages[0].content
          // 当有会话列表的情况下
          if (this.JIMUserList.length) {
            let existUser = null
            // 插入信息
            this.JIMUserList.forEach((user, idx) => {
              if (user.adminId == content.from_id) {
                let body = content.msg_body.text
                body = /"goods_main_photo"/.test(body) ? JSON.parse(body) : body
                user.message.push({
                  text: body,
                  goods: typeof body == 'object'
                })
                existUser = this.JIMUserList.splice(idx, 1)[0]
                return
              }
            })
            if (existUser) {
              // 把当前的信息置顶
              this.JIMUserList.unshift(existUser)
            } else {
              this._addUserInexistence(content)
            }
          } else {
            this._addUserInexistence(content)
          }
          // 聊天时，让滚动条始终在底部
          this._scrollToBottom()
        })
      },
      // 发送消息
      onSendMsg() {
        const _this = this
        // 发送的目标对象
        const target = this.JIMTargetUser
        if (!target.adminId) {
          this.isNoSend = true
          return
        }
        // 发送的参数
        const oParams = {
          adminId: target.adminId || '', // 平台创建ID
          goodsId: target.goodsId || '', // 商品Id
          storeId: target.storeId + '', // 店铺id
          buyName: target.buyName || '', // 买家名称
          buyImg: target.buyImg || '', // 买家头像
          buyId: target.buyId, // 买家手机号
          storeName: target.storeName || '', // 店铺名称
          storeLogo: target.storeLogo || '', // 店铺头像
          customerPhone: target.customerPhone || '', // 客服手机号
          storePhone: target.storePhone || '', // 店铺拥有者的手机号
          userType: 'SELLER' // 发送者用户类型
        }
        // 只有输了值，才可以发送消息，否则不操作
        if (this.chatMsg.trim()) {
          // 发送（本平台）消息
          apiChatSendMsg({
            body: this.chatMsg, // 发送的消息
            ...oParams
          })
           // 发送（极光）信息
          JIM.sendSingleMsg({
            'target_username': target.adminId,
            'target_nickname': target.storeName,
            'content': this.chatMsg,
            'appkey': this.appkey,
            'extras': oParams
          }).onSuccess(data => {
            // 正常的文字消息
            target.message.push({
              text: _this.chatMsg,
              ident: true // true则是自己发送的
            })
            _this._scrollToBottom()
            _this.chatMsg = ''
          })
        }
      },
      // 接受消息时，如果当前没有用户，则添加该用户
      _addUserInexistence(content) {
        const isGoods = content.msg_body.extras.goodsId
        const newUser = {
          ...content.msg_body.extras,
          adminId: content.from_id,
          message: [{
            text: isGoods ? JSON.parse(content.msg_body.text) : content.msg_body.text,
            goods: isGoods
          }]
        }
        this.JIMUserList.unshift(newUser)
        if (this.JIMUserList.length == 1) {
          this.setJIMTargetUser(newUser)
        }
      },
      // 打开聊天窗口时，让滚动条始终在底部
      _scrollToBottom() {
        const chatBody = document.getElementById('chatBody')
        setTimeout(() => {
          if (chatBody) {
            chatBody.scrollTop = chatBody && chatBody.scrollHeight
          }
        }, 14)
      },
      // 关闭聊天窗口
      onCloseJIM() {
        this.$router.go(-1)
      },
      // 切换联系人
      onSelectUser(user) {
        if (user.adminId == this.JIMTargetUser.adminId) return
        this.setJIMTargetUser(user)
        this._scrollToBottom()
      },
      // 控制表情框显示隐藏
      onEmojiVisible() {
        this.isEmoji = !this.isEmoji
      },
      // 点击选择表情
      onSelectEmoji(emoji) {
        this.chatMsg += emoji
        this.isEmoji = false
        document.getElementById('chatMsg').focus()
      },
      // 店家输入框
      onClickText() {
        if (this.isEmoji) {
          this.isEmoji = false
        }
      }
    },
    computed: {
      ...mapGetters(['JIMUserList', 'JIMTargetUser'])
    },
    filters: {
      filterLastMsg(val) {
        if (typeof val == 'string') {
          return val
        } else {
          return (val.goodsName || '')
        }
      }
    }
  }
</script>

<style lang="scss" scoped>
  @import '../../scss/_mixin.scss';
  $c-bd: #e2e2e2;

  .m-chat {
    position: fixed;
    left: 50%;
    top: 50%;
    width: 1100px;
    height: 600px;
    transform: translate(-50%, -50%);
    z-index: 50;
    background: #fff;
  }
  // 聊天侧边栏
  .m-chat-aside {
    position: absolute;
    left: 0;
    top: 0;
    bottom: 0;
    width: 220px;
    overflow-y: auto;
    background: #f00384;

    .JIMUserList-null {
      padding-top: 20px;
      font-size: 16px;
      color: #fff;
      text-align: center;
    }

    .list {
      height: 70px;
      padding: 0 10px;
      color: #fff;
      cursor: pointer;
      &.actived {
        background: #de68a8;
      }
      .avatar {
        float: left;
        width: 40px;
        height: 40px;
        margin-top: 15px;
        margin-right: 10px;
        border-radius: 20px;
        overflow: hidden;
      }
      .ct {
        padding-top: 15px;
        .name {
          @include curoff(130px);
        }
        .msg-bd {
          margin-top: 10px;
          font-size: 12px;
        }
        .msg {
          @include curoff(130px);
        }
      }
    }
  }
  // 聊天头
  .m-chat-bd {
    position: absolute;
    left: 220px;
    right: 0;
    top: 0;
    bottom: 0;
    overflow: hidden;
    border: 1px solid $c-bd;
    background: #fff;
    // 商家店铺名称和关闭
    header {
      position: relative;
      height: 44px;
      padding: 0 18px;
      line-height: 44px;
      border-bottom: 1px solid $c-bd;
      .name {
        font-size: 18px;
        font-weight: 400;
        color: #6a6a6a;
      }
      .indicator {
        display: inline-block;
        width: 10px;
        height: 10px;
        background: #f00384;
        border-radius: 6px;
      }
      .close {
        position: absolute;
        right: 0;
        top: 0;
        bottom: 0;
        width: 44px;
        height: 44px;
        background: url(./ico_close.png) no-repeat center center;
        cursor: pointer;
      }
    }
    // 工具栏
    .tool-bd {
      position: absolute;
      bottom: 130px;
      left: 0;
      right: 0;
      height: 38px;
      padding: 10px 18px 0 18px;
      border-top: 1px solid $c-bd;
      .face {
        width: 20px;
        height: 20px;
        background: url(./ico_face.png) no-repeat center center;
      }
    }
    // 输入框
    .input-bd {
      position: absolute;
      bottom: 0;
      left: 0;
      right: 0;
      height: 130px;
      overflow-y: auto;
      textarea {
        background: #fff;
      }
      button {
        position: absolute;
        right: 66px;
        bottom: 14px;
        width: 80px;
        height: 36px;
        border-radius: 3px;
        font-size: 18px;
        color: #fef3f8;
      }
    }
  }
  // 聊天内容
  .chat-bd {
    position: absolute;
    left: 0;
    right: 0;
    top: 50px;
    bottom: 168px;
    overflow-y: auto;
    .msg-bd {
      @include clearfix();
      padding: 14px;
      .avatar {
        width: 40px;
        height: 40px;
        border-radius: 20px;
        border: 1px solid #e1e1e1;
        overflow: hidden;
      }
      .ct {
        width: 420px;
        padding: 10px;
        background: #e8e8e8;
        word-break: break-all;
        color: #828282;
        line-height: 24px;
      }
      .photo-text {
        height: 80px;
        img {
          width: 60px;
        }
      }
    }
    .opposite-msg-bd {
      .avatar {
        margin-right: 10px;
      }
      .avatar, .ct {
        float: left;
      }
      .photo-text img {
        float: right;
        margin-left: 10px;
      }
    }
    .mine-msg-bd {
      .avatar {
        margin-left: 10px;
      }
      .avatar, .ct {
        float: right;
      }
      .photo-text img {
        float: left;
        margin-right: 10px;
      }
    }
  }
  // 输入内容
  #chatMsg {
    padding: 10px 18px;
    height: 130px;
    outline: none;
    border: none;
  }
</style>